package com.ww.learn.generic

import java.lang.RuntimeException

abstract class Book(val name: String)
class Fiction(name: String): Book(name)
class NonFiction(name: String): Book(name)

fun <T> findFirst(books: List<Book>, ofClass: Class<T>): T {
    val selected = books.filter { book -> ofClass.isInstance(book) }
    if (0 == selected.size) {
        throw RuntimeException("Not found")
    }
    return ofClass.cast(selected[0])
}

// 在函数中使用T类执行类型检查和类型转换，只能对内联函数使用reified
// 函数体将在函数调用的位置扩展
inline fun <reified T> findFirst2(books: List<Book>): T {
    val selected = books.filter { book -> book is T }

    if (0 == selected.size) {
        throw RuntimeException("Not found")
    }

    return selected[0] as T
}

fun main() {
    val books: List<Book> = listOf(
        Fiction("Moby Dick"), NonFiction("Learn to Code"), Fiction("LOTR"))
    println(findFirst(books, Fiction::class.java).name)
    println(findFirst(books, NonFiction::class.java).name)
    println(findFirst(books, Book::class.java).name)

    println(findFirst2<NonFiction>(books).name)
}